﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cleverscape.UTorrentClient.WebClient;

namespace uTorrentNetClient.ModelDesign.Helper
{
    public class TorrentDecorator : Base
    {
        public TorrentDecorator(Torrent torrent)
        {
            Torrent = torrent;

            Hash = torrent.Hash;

            SimpleStatus = torrent.SimpleStatus;
            Name = torrent.Name;
            QueueOrder = torrent.QueueOrder;
            SizeTotalBytes = torrent.SizeTotalBytes;
            SizeDownloadedBytes = torrent.SizeDownloadedBytes;
            SizeRemainingBytes = torrent.SizeRemainingBytes;
            ProgressPercent = torrent.ProgressPercent;
            Seeds = torrent.Seeds;
            Peers = torrent.Peers;
            SeedsPeersRatio = torrent.SeedsPeersRatio;
            SpeedDownloadBytes = torrent.SpeedDownloadBytes;
            SpeedUploadBytes = torrent.SpeedUploadBytes;
            TimeEstimate = torrent.TimeEstimate;
            SizeUploadedBytes = torrent.SizeUploadedBytes;
            SeedRatio = torrent.SeedRatio;
            Availability = torrent.Availability;
            Label = torrent.Label;
            DHT = torrent.UseDistributedHashTable;
            PEX = torrent.UsePeerExchange;
            MaximumUploadBytesPerSecond = torrent.MaximumUploadBytesPerSecond;
            MaximumDownloadBytesPerSecond = torrent.MaximumDownloadBytesPerSecond;
            MaximumSeedRatio = torrent.MaximumSeedRatio;
            MaximumSeedTime = torrent.MaximumSeedTime;
            InitialSeeding = torrent.InitialSeeding;
            OverrideQueueing = torrent.OverrideQueueing;

            Files = new List<TorrentFileDecorator>();
            foreach (var file in torrent.Files)
            {
                Files.Add(new TorrentFileDecorator(file));
            }

            Trackers = new List<Tracker>();
            foreach (var tracker in torrent.Trackers)
            {
                Trackers.Add(tracker);
            }

            ResetChanges();
        }

        public Torrent Torrent { get; private set; }

        public string Hash { get; set; }

        public TorrentSimpleStatus SimpleStatus { get; private set; }
        public string Name { get; private set; }
        public int QueueOrder { get; private set; }
        public long SizeTotalBytes { get; private set; }
        public long SizeDownloadedBytes { get; private set; }
        public long SizeRemainingBytes { get; private set; }
        public decimal ProgressPercent { get; private set; }
        public string Seeds { get; private set; }
        public string Peers { get; private set; }
        public decimal SeedsPeersRatio { get; private set; }
        public long SpeedDownloadBytes { get; private set; }
        public long SpeedUploadBytes { get; private set; }
        public TimeSpan TimeEstimate { get; private set; }
        public long SizeUploadedBytes { get; private set; }
        public decimal SeedRatio { get; private set; }
        public decimal Availability { get; private set; }
        public string Label { get; private set; }

        private OptionValue _dht;
        public OptionValue DHT
        {
            get { return _dht; }
            set
            {
                setHasChanges(_dht, value);
                _dht = value;
                SetNotifyPropertyChanged("DHT");
            }
        }

        private OptionValue _pex;
        public OptionValue PEX
        {
            get { return _pex; }
            set
            {
                setHasChanges(_pex, value);
                _pex = value;
                SetNotifyPropertyChanged("PEX");
            }
        }

        private long _maximumUploadBytesPerSecond;
        public long MaximumUploadBytesPerSecond 
        {
            get
            {
                return _maximumUploadBytesPerSecond == 0 ? 0 : _maximumUploadBytesPerSecond / 1000;
            }
            set
            {
                
                setHasChanges(_maximumUploadBytesPerSecond, value * 1000);
                _maximumUploadBytesPerSecond = value * 1000;
                SetNotifyPropertyChanged("MaximumUploadBytesPerSecond");
            }
        }

        private long _maximumDownloadBytesPerSecond;
        public long MaximumDownloadBytesPerSecond
        {
            get { return _maximumDownloadBytesPerSecond == 0 ? 0 : _maximumDownloadBytesPerSecond / 1000; }
            set
            {
                setHasChanges(_maximumDownloadBytesPerSecond, value * 1000);
                _maximumDownloadBytesPerSecond = value * 1000;
                SetNotifyPropertyChanged("MaximumDownloadBytesPerSecond");
            }
        }

        private TimeSpan _maximumSeedTime;
        public TimeSpan MaximumSeedTime
        {
            get { return _maximumSeedTime; }
            set
            {
                setHasChanges(_maximumSeedTime, value);
                _maximumSeedTime = value;
                SetNotifyPropertyChanged("MaximumSeedTime");
            }
        }

        private decimal _maximumSeedRatio;
        public decimal MaximumSeedRatio
        {
            get { return _maximumSeedRatio; }
            set
            {
                setHasChanges(_maximumSeedRatio, value);
                _maximumSeedRatio = value;
                SetNotifyPropertyChanged("MaximumSeedRatio");
            }
        }

        private int _uploadSlots;
        public int UploadSlots
        {
            get { return _uploadSlots; }
            set
            {
                setHasChanges(_uploadSlots, value);
                _uploadSlots = value;
                SetNotifyPropertyChanged("UploadSlots");
            }
        }

        private OptionValue _initialSeeding;
        public OptionValue InitialSeeding
        {
            get { return _initialSeeding; }
            set
            {
                setHasChanges(_initialSeeding, value);
                _initialSeeding = value;
                SetNotifyPropertyChanged("InitialSeeding");
            }
        }

        private OptionValue _overrideQueueing;
        public OptionValue OverrideQueueing
        {
            get { return _overrideQueueing; }
            set
            {
                setHasChanges(_overrideQueueing, value);
                _overrideQueueing = value;
                SetNotifyPropertyChanged("OverrideQueueing");
            }
        }

        private List<TorrentFileDecorator> _files;
        public List<TorrentFileDecorator> Files
        {
            get { return _files; }
            set
            {
                _files = value;
                SetNotifyPropertyChanged("Files");
            }
        }

        private List<Tracker> _trackers;
        public List<Tracker> Trackers
        {
            get { return _trackers; }
            set
            {
                _trackers = value;
                SetNotifyPropertyChanged("Trackers");
            }
        }

        public void SaveChanges()
        {
            if(HasChanges)
            {
                Torrent.UseDistributedHashTable = DHT;
                Torrent.UsePeerExchange = PEX;
                Torrent.MaximumUploadBytesPerSecond = MaximumUploadBytesPerSecond;
                Torrent.MaximumDownloadBytesPerSecond = MaximumDownloadBytesPerSecond;
                Torrent.MaximumSeedRatio = MaximumSeedRatio;
                Torrent.MaximumSeedTime = MaximumSeedTime;
                Torrent.UploadSlots = UploadSlots;

                ResetChanges();
            }

            foreach (var file in Files)
            {
                if(file.HasChanges)
                    file.SaveChanges();
            }
        }
    }
}
